home *** CD-ROM | disk | FTP | other *** search
/ Fritz: All Fritz / All Fritz.zip / All Fritz / FILES / PROGNG_C / MRUTC.LZH / ENTRY.C < prev    next >
Text File  |  1988-04-10  |  8KB  |  402 lines

  1. /* --------- entry.c ---------- */
  2.  
  3. #include <stdio.h>
  4. #include <ctype.h>
  5. #include <stdlib.h>
  6. #include <alloc.h>
  7. #include <mem.h>
  8. #include <string.h>
  9. #include "twindow.h"
  10. #include "keys.h"
  11.  
  12. #define FIELDCHAR '_'
  13. int insert_mode = FALSE;       /* insert mode, TRUE/FALSE */
  14. extern int helpkey;
  15.  
  16. /* -------- local prototypes -------- */
  17. void addfield(WINDOW *wnd, FIELD *fld);
  18. void disp_field(WINDOW *wnd, char *bf, char *msk);
  19. void data_value(WINDOW *wnd, FIELD *fld);
  20. void insert_status(void);
  21. int read_field(WINDOW *wnd, FIELD *fld);
  22. void right_justify(char *s);
  23. void right_justify_zero_fill(char *s);
  24. int validate_date(char *s);
  25. int endstroke(int c);
  26. int spaces(char *c);
  27.  
  28. /* -------- initialize a template --------- */
  29. void init_template(WINDOW *wnd)
  30. {
  31.     remove_delist(wnd);
  32.     FHEAD = FTAIL = NULL;
  33. }
  34.  
  35. /* ------ establish a field in a template ------- */
  36. FIELD *establish_field(wnd, cl, rw, msk, bf, ty)
  37. WINDOW *wnd;
  38. int rw;
  39. int cl;
  40. char *msk;
  41. char *bf;
  42. int ty;
  43. {
  44.     FIELD *fld;
  45.  
  46.     if ( (fld = malloc(sizeof(FIELD))) == NULL)
  47.         return NULL;
  48.     fld->fmask = msk;
  49.     fld->frow = rw;
  50.     fld->fcol = cl;
  51.     fld->fbuff = bf;
  52.     fld->ftype = ty;
  53.     fld->fprot = 0;
  54.     fld->fnxt = fld->fprv = NULL;
  55.     fld->fvalid = NULL;
  56.     fld->fhelp = NULL;
  57.     fld->fhwin = NULL;
  58.     fld->flx = fld->fly = 0;
  59.     addfield(wnd, fld);
  60.     return fld;
  61. }
  62.  
  63. /* ----- add a field to the end of the list ------ */
  64. static void addfield(WINDOW *wnd, FIELD *fld)
  65. {
  66.     if (FTAIL)    {
  67.         fld->fprv = FTAIL;
  68.         FTAIL->fnxt = fld;
  69.     }
  70.     FTAIL = fld;
  71.     if (!FHEAD)
  72.         FHEAD = fld;
  73. }
  74.  
  75. /* -------- display a data field ------ */
  76. static void disp_field(WINDOW *wnd, char *bf, char *msk)
  77. {
  78.     while (*msk)    {
  79.         wputchar(wnd, *msk != FIELDCHAR ? *msk : *bf++);
  80.         msk++;
  81.     }
  82. }
  83.  
  84. /* ------- display the data value in a field ------ */
  85. static void data_value(WINDOW *wnd, FIELD *fld)
  86. {
  87.     wcursor(wnd, fld->fcol, fld->frow);
  88.     disp_field(wnd, fld->fbuff, fld->fmask);
  89. }
  90.  
  91. /* ------ display all the fields in a window ------- */
  92. void field_tally(WINDOW *wnd)
  93. {
  94.     FIELD *fld;
  95.  
  96.     fld = FHEAD;
  97.     while (fld != NULL)    {
  98.         data_value(wnd, fld);
  99.         fld = fld->fnxt;
  100.     }
  101. }
  102.  
  103. /* ----- set a field's help window ------- */
  104. void field_window(FIELD *fld, char *hwin, int x, int y)
  105. {
  106.     fld->fhwin=hwin;
  107.     fld->flx = x;
  108.     fld->fly = y;
  109. }
  110. /*page*/
  111. /* ------- clear a template to all blanks ------ */
  112. void clear_template(WINDOW *wnd)
  113. {
  114.     FIELD *fld;
  115.     char *bf, *msk;
  116.  
  117.     fld = FHEAD;
  118.     while (fld != NULL)    {
  119.         bf = fld->fbuff;
  120.         msk = fld->fmask;
  121.         while (*msk)    {
  122.             if (*msk == FIELDCHAR)
  123.                 *bf++ = ' ';
  124.             msk++;
  125.         }
  126.         fld = fld->fnxt;
  127.     }
  128.     field_tally(wnd);
  129. }
  130.  
  131. /* ---------- set insert/exchange cursor shape ----------- */
  132. static void insert_status()
  133. {
  134.     set_cursor_type(insert_mode ? 0x0106 : 0x0607);
  135. }
  136. /*page*/
  137. /* ------- read a field from the keyboard ------------- */
  138. static int read_field(WINDOW *wnd, FIELD *fld)
  139. {
  140.     char *mask = fld->fmask, *buff = fld->fbuff;
  141.     int done = FALSE, c, column;
  142.  
  143.     column = fld->fcol;
  144.     while (*mask != FIELDCHAR)    {
  145.         column++;
  146.         mask++;
  147.     }
  148.     while (TRUE)    {
  149.         wcursor(wnd, column, fld->frow);
  150.         c = get_char();
  151.         if (fld->ftype == 'A')
  152.             c = toupper(c);
  153.         clear_message();
  154.         switch (c)    {
  155.             case '\b':
  156.             case BS:
  157.                 if (buff == fld->fbuff)    {
  158.                     done = c == BS;
  159.                     break;
  160.                 }
  161.                 --buff;
  162.                 do    {
  163.                     --mask;
  164.                     --column;
  165.                 } while (*mask != FIELDCHAR);
  166.                 if (c == BS)
  167.                     break;
  168.             case DEL:
  169.                 movmem(buff+1, buff, strlen(buff));
  170.                 *(buff+strlen(buff)) = ' ';
  171.                 wcursor(wnd, column, fld->frow);
  172.                 disp_field(wnd, buff, mask);
  173.                 break;
  174.             case FWD:
  175.                 do    {
  176.                     column++;
  177.                     mask++;
  178.                 } while (*mask && *mask != FIELDCHAR);
  179.                 buff++;
  180.                 break;
  181.             case INS:
  182.                 insert_mode ^= TRUE;
  183.                 insert_status();
  184.                 break;
  185.             case '.':
  186.                 if (fld->ftype == 'C')    {
  187.                     if (*mask++ && *buff == ' ')    {
  188.                         *buff++ = '0';
  189.                         if (*mask++ && *buff == ' ')
  190.                             *buff++ = '0';
  191.                     }
  192.                     right_justify(fld->fbuff);
  193.                     wcursor(wnd, fld->fcol, fld->frow);
  194.                     disp_field(wnd, fld->fbuff, fld->fmask);
  195.                     column = fld->fcol+strlen(fld->fmask)-2;
  196.                     mask = fld->fmask+strlen(fld->fmask)-2;
  197.                     buff = fld->fbuff+strlen(fld->fbuff)-2;
  198.                     break;
  199.                 }
  200.             default:
  201.                 if (endstroke(c))    {
  202.                     done = TRUE;
  203.                     break;
  204.                 }
  205.                 if (toupper(fld->ftype)!='A'&&!isdigit(c))    {
  206.                     error_message("Numbers only");
  207.                     break;
  208.                 }
  209.                 if (insert_mode)    {
  210.                     movmem(buff, buff+1, strlen(buff)-1);
  211.                     disp_field(wnd, buff, mask);
  212.                     wcursor(wnd, column, fld->frow);
  213.                 }
  214.                 *buff++ = c;
  215.                 wputchar(wnd, c);
  216.                 do    {
  217.                     column++;
  218.                     mask++;
  219.                 } while (*mask && *mask != FIELDCHAR);
  220.                 if (!*mask)
  221.                     c = FWD;
  222.                 break;
  223.         }
  224.         if (!*mask)
  225.             done = TRUE;
  226.         if (done)    {
  227.             if (fld->ftype == 'D' &&
  228.                     c != ESC &&
  229.                         validate_date(fld->fbuff) != OK)
  230.                 return ERROR;
  231.             break;
  232.         }
  233.     }
  234.     if (c != ESC && toupper(fld->ftype) != 'A')    {
  235.         if (fld->ftype == 'C')    {
  236.             if (*mask++ && *buff == ' ')    {
  237.                 *buff++ = '0';
  238.                 if (*mask++ && *buff == ' ')
  239.                     *buff++ = '0';
  240.             }
  241.         }
  242.         if (fld->ftype == 'Z' || fld->ftype == 'D')
  243.             right_justify_zero_fill(fld->fbuff);
  244.         else
  245.             right_justify(fld->fbuff);
  246.         wcursor(wnd, fld->fcol, fld->frow);
  247.         disp_field(wnd, fld->fbuff, fld->fmask);
  248.     }
  249.     return c;
  250. }
  251. /*page*/
  252. /* ---------- test c for an ending keystroke ----------- */
  253. static int endstroke(int c)
  254. {
  255.     switch (c)    {
  256.         case '\r':
  257.         case '\n':
  258.         case '\t':
  259.         case ESC:
  260.         case F1:
  261.         case F2:
  262.         case F3:
  263.         case F4:
  264.         case F5:
  265.         case F6:
  266.         case F7:
  267.         case F8:
  268.         case F9:
  269.         case F10:
  270.         case PGUP:
  271.         case PGDN:
  272.         case HOME:
  273.         case END:
  274.         case UP:
  275.         case DN:
  276.             return TRUE;
  277.         default:
  278.             return FALSE;
  279.     }
  280. }
  281. /*page*/
  282. /* ------- right justify, space fill -------- */
  283. static void right_justify(char *s)
  284. {
  285.     int len;
  286.  
  287.     len = strlen(s);
  288.     while (*s == ' ' || *s == '0' && len)    {
  289.         len--;
  290.         *s++ = ' ';
  291.     }
  292.     if (len)
  293.         while (*(s+(len-1)) == ' ')    {
  294.             movmem(s, s+1, len-1);
  295.             *s = ' ';
  296.         }
  297. }
  298.  
  299. /* ---------- right justify, zero fill --------------- */
  300. static void right_justify_zero_fill(char *s)
  301. {
  302.     int len;
  303.  
  304.     if (spaces(s))
  305.         return;
  306.     len = strlen(s);
  307.     while (*(s + len - 1) == ' ')    {
  308.         movmem(s, s + 1, len-1);
  309.         *s = '0';
  310.     }
  311. }
  312.  
  313. /* ----------- test for spaces -------- */
  314. int spaces(char *c)
  315. {
  316.     while (*c == ' ')
  317.         c++;
  318.     return !*c;
  319. }
  320. /*page*/
  321. /* -------------- validate a date ----------------- */
  322. static int validate_date(char *s)
  323. {
  324.     static int days [] =
  325.         { 31,28,31,30,31,30,31,31,30,31,30,31 };
  326.     char date [7];
  327.     int mo;
  328.  
  329.     strcpy(date, s);
  330.     if (spaces(date))
  331.         return OK;
  332.     days[1] = (atoi(date+4)%4) ? 28 : 29;
  333.     *(date + 4) = '\0';
  334.     mo = atoi(date+2);
  335.     *(date+2) = '\0';
  336.     if (mo && mo<13 && atoi(date) && atoi(date)<=days[mo-1])
  337.         return OK;
  338.     error_message("Invalid date");
  339.     return ERROR;
  340. }
  341.  
  342. /* ----- Process data entry for a screen template. ---- */
  343. int data_entry(WINDOW *wnd)
  344. {
  345.     FIELD *fld;
  346.     int exitcode, isvalid, done=FALSE, oldhelpkey=helpkey;
  347.     field_tally(wnd);
  348.     fld = FHEAD;
  349.     /* ---- collect data from keyboard into screen ---- */
  350.     while (fld != NULL && done == FALSE)    {
  351.         set_help(fld->fhwin, fld->flx, fld->fly);
  352.         helpkey = (fld->fhelp) ? 0 : oldhelpkey;
  353.         wcursor(wnd, fld->fcol, fld->frow);
  354.         if (fld->fprot == FALSE)    {
  355.             reverse_video(wnd);
  356.             data_value(wnd, fld);
  357.             wcursor(wnd, fld->fcol, fld->frow);
  358.             exitcode = read_field(wnd, fld);
  359.             isvalid = (exitcode != ESC && fld->fvalid) ?
  360.                         (*(fld->fvalid))(fld->fbuff) : OK;
  361.         }
  362.         else    {
  363.             exitcode = FWD;
  364.             isvalid = OK;
  365.         }
  366.         if (isvalid == OK)    {
  367.             normal_video(wnd);
  368.             data_value(wnd, fld);
  369.             switch (exitcode)    {        /* passed edit */
  370.                 case F1:    if (fld->fhelp)    {
  371.                                 (*(fld->fhelp))(fld->fbuff);
  372.                                 data_value(wnd, fld);
  373.                             }
  374.                             break;
  375.                 case DN:
  376.                 case '\r':
  377.                 case '\t':
  378.                 case FWD:    fld = fld->fnxt;
  379.                             if (fld == NULL)
  380.                                 fld = FHEAD;
  381.                             break;
  382.                 case UP:
  383.                 case BS:    fld = fld->fprv;
  384.                             if (fld == NULL)
  385.                                 fld = FTAIL;
  386.                             break;
  387.                 default:    done = endstroke(exitcode);
  388.                             break;
  389.             }
  390.         }
  391.     }
  392.     helpkey = oldhelpkey;
  393.     return (exitcode);
  394. }
  395. /* --------- display a window prompt -------- */
  396. void wprompt(WINDOW *wnd, int x, int y, char *s)
  397. {
  398.     wcursor(wnd, x, y);
  399.     wprintf(wnd, s);
  400. }
  401.  
  402.